"""
.. module:: nodelogger
.. moduleauthor:: @author: 

The purpose of this module is to manage logging.

Note: 
    The user must first call::
    
        NodeLogger::load()
    
    to initialise all logging handles. This can be called directly for standalone
    tests. However it is also called from::
    
        Runtime::start_service_manager_and_config_service()
    
*Constants*:

.. seealso:: class :class:`runtime.rt.Runtime`
"""

# Imports
#
import logging

# Constants
#

# Classes
#

class NodeLogger(object):
    """
    This class manages logging handles.
    
    **Constants**:
    """
    
    # Log Levels...
    #
    DEVEL = 15   # Data to support a developer writing a new task.
    TRACE = 5    # Lots of output to fix gnarly bugs  
    DFLT_LOGLEVEL = logging.DEBUG
    
    logger_names = {'yarra.datastore.database': logging.ERROR,
                    'yarra.datastore.database.DataStore': logging.ERROR,
                    'yarra.datastore.database_test': logging.ERROR,
                    'yarra.datastore.database_test.DataStoreTest': logging.ERROR,
                    'yarra.datastore.resource': logging.ERROR,
                    'yarra.datastore.resource.Resource': logging.ERROR,
                    'yarra.datastore.resource_test': logging.ERROR,
                    'yarra.datastore.resource_test.ResourceTest': logging.ERROR,
                    'yarra.datastore.spaces': logging.ERROR,
                    'yarra.datastore.spaces.Spaces': logging.ERROR,
                    'yarra.datastore.spaces_test': logging.ERROR,
                    'yarra.datastore.spaces_test.SpacesTest': logging.ERROR,
                    'yarra.datastore.uri': logging.ERROR,
                    'yarra.datastore.uri.Uri': logging.ERROR,
                    'yarra.datastore.uri_test': logging.ERROR,
                    'yarra.datastore.uri_test.UriTest': logging.ERROR,
                    'yarra.runtime.node': logging.ERROR,
                    'yarra.runtime.node.TCPServerHandler': logging.ERROR,
                    'yarra.runtime.node.NodeServer': logging.ERROR,
                    'yarra.runtime.node.Install': logging.ERROR,
                    'yarra.runtime.node.DataStore': logging.ERROR,
                    'yarra.runtime.node.MetaLoader': logging.ERROR,
                    'yarra.runtime.node.MetaFinder': logging.INFO,
                    'yarra.runtime.rt': logging.ERROR,
                    'yarra.runtime.rt.NodeService': logging.ERROR,
                    'yarra.runtime.rt.RunTime': logging.ERROR,
                    'yarra.runtime.service': logging.ERROR,
                    'yarra.runtime.service.Service': logging.ERROR,
                    'yarra.runtime.service_test': logging.ERROR,
                    'yarra.runtime.service_test.ServiceTest': logging.ERROR,
                    'yarra.services.config_service': logging.ERROR,
                    'yarra.services.config_service.ConfigService': logging.ERROR,
                    'yarra.services.dev_autoload_service': logging.ERROR,
                    'yarra.services.dev_autoload_service.DevAutoloadService': logging.ERROR,
                    'yarra.services.htmltemplate': logging.ERROR,
                    'yarra.services.htmltemplate.YarraBase': logging.ERROR,
                    'yarra.services.htmltemplate.YarraList': logging.ERROR,
                    'yarra.services.htmltemplate.YarraCond': logging.ERROR,
                    'yarra.services.htmltemplate.YarraVar': logging.ERROR,
                    'yarra.services.htmltemplate.YarraData': logging.ERROR,
                    'yarra.services.htmltemplate.YarraHTMLParser': logging.ERROR,
                    'yarra.services.htmltemplate.YarraIncludeParser': logging.ERROR,
                    'yarra.services.htmltemplate.HTMLTemplate': logging.ERROR,
                    'yarra.services.http_service': logging.ERROR,
                    'yarra.services.http_service.HTTPService': logging.ERROR,
                    'yarra.services.http_service.Server': logging.ERROR,
                    'yarra.services.http_service.Handler': logging.ERROR,
                    'yarra.services.service_manager_service': logging.DEBUG,
                    'yarra.services.service_manager_service.ServiceManagerService': logging.DEBUG,
                    'yarra.basesite.services.showdatastore_service': logging.ERROR,
                    'yarra.basesite.services.showdatastore_service.ShowDataStoreService': logging.ERROR,
                    'yarra.basesite.services.showspaces_service': logging.ERROR,
                    'yarra.basesite.services.showspaces_service.ShowSpacesService': logging.ERROR,
                    'yarra.basesite.services.support_service': logging.ERROR,
                    'yarra.basesite.services.support_service.SupportService': logging.ERROR,
                    'yarra.services.time_service': logging.ERROR,
                    'yarra.services.time_service.TimeService': logging.ERROR,
                    'yarra.services.logger_service': logging.ERROR,
                    'yarra.services.logger_service.LoggerService': logging.ERROR,
                 
                    'eplanning.spear.a2p_service': logging.ERROR,
                    'eplanning.spear.a2p_service.A2PServiceAPI': logging.ERROR,
                    'eplanning.spear.a2p_service.A2PService': logging.ERROR,
                    'eplanning.spear.a2p_servicetest': logging.ERROR,
                    'eplanning.spear.a2p_servicetest.A2PServiceTest': logging.ERROR,
                    'eplanning.spear.a2pdatastore_service': logging.ERROR,
                    'eplanning.spear.a2pdatastore_service.A2PDataStoreService': logging.ERROR,
                    'eplanning.spear.a2pdatastore_servicetest': logging.ERROR,
                    'eplanning.spear.a2pdatastore_servicetest.A2PDataStoreServiceTest': logging.ERROR,
                    'eplanning.spear.a2pspear_service': logging.ERROR,
                    'eplanning.spear.a2pspear_service.A2PSpearService': logging.ERROR,
                    'eplanning.spear.a2pspear_servicetest': logging.ERROR,
                    'eplanning.spear.a2pspear_servicetest.A2PSpearServiceTest': logging.ERROR,
                    'eplanning.spear.http': logging.ERROR,
                    'eplanning.spear.http.HTTP': logging.ERROR
                    }
    loggers = {}

    @staticmethod
    def load():
        """
        Create loggers for all configured modules. This must be called before
        other methods.
        """                
        for m in NodeLogger.logger_names.keys():
            NodeLogger.loggers[m] = logging.getLogger(m)
            NodeLogger.loggers[m].setLevel(NodeLogger.logger_names[m])
    
    @staticmethod
    def getLogger(logger_name):
        """
        Return the logger handle for the argument module name.
        
        :param module_name: The module name.
        """
        
        if (logger_name in NodeLogger.logger_names):
            return NodeLogger.loggers[logger_name]
        
        logger = logging.getLogger(logger_name)
        logger.setLevel(NodeLogger.DFLT_LOGLEVEL)
        
        return logger
    
    @staticmethod
    def setRootLevel(level):
        """
        Set the logging level of the root logger.
        
        :param level: The logging level.
        """
        
        logging.root.setLevel(level)
    
    @staticmethod
    def setLevel(logger_name, level):
        """
        Set the logging level of the logger of the argument module name.
        
        :param module_name: The module name.
        :param level: The logging level.
        """
        
        if (logger_name in NodeLogger.logger_names):
            NodeLogger.loggers[logger_name].setLevel(level)
            
    @staticmethod
    def setStreamHandler():
        streamHandler = logging.StreamHandler()
        formatter = logging.Formatter(
                        "[%(asctime)s %(levelname)-8s %(threadName)s %(name)s " + \
                        "%(module)s:%(lineno)d::%(funcName)s] %(message)s")
        streamHandler.setFormatter(formatter)
        logging.root.addHandler(streamHandler)        